import type { App } from 'vue';

interface IWatermarkOptions {
  fontSize?: number;
  color?: string;
  angle?: number;
  padding?: number;
  watch?: boolean;
}
export const generateWatermark = (
  text: string,
  options: IWatermarkOptions = {}
) => {
  const {
    fontSize = 16,
    color = 'rgba(0,0,0,0.2)',
    angle = -30,
    padding = 100
  } = options;

  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d')!;

  // 根据文字长度调整Canvas尺寸
  // canvas的宽高要在最开始设置
  ctx.font = `${fontSize}px Arial`;
  const textWidth = ctx.measureText(text).width + padding;
  canvas.width = textWidth;
  canvas.height = textWidth;
  ctx.clearRect(0, 0, textWidth, textWidth);

  // 如果在设置 canvas.width 和 canvas.height 之前调用 ctx.font，那么此时 Canvas 的分辨率可能还是默认值（300x150），导致绘制的文字大小被压缩或拉伸
  // 所以文字的设置要放在 canvas.width 和 canvas.height 之后
  ctx.font = `${fontSize}px Arial`;
  // 绘制旋转文字
  ctx.translate(textWidth / 2, textWidth / 2); // 坐标系平移到中间
  ctx.rotate((Math.PI / 180) * angle); // 旋转角度
  ctx.fillStyle = color;
  ctx.textAlign = 'center'; // 文字水平居中，那么文字中间就位于坐标系原点
  ctx.textBaseline = 'middle'; // 文字垂直居中，那么文字中间就位于坐标系原点
  ctx.fillText(text, 0, 0); // 绘制文字
  const base64Url = canvas.toDataURL();
  return base64Url;
};

export const watermarkDirective = (app: App<Element>) => {
  app.directive('watermark', {
    mounted(el, binding) {
      const { text, ...options } = binding.value;
      const base64Url = generateWatermark(text, options);
      const div = document.createElement('div');
      div.style.cssText = `
        position: fixed;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        background-image: url('${base64Url}');
        background-repeat: repeat;
        pointer-events: none;
        z-index: 9999;
      `;
      el._watermark = div;
      console.log('=====', document.body.contains(div));
      if (!document.body.contains(div)) {
        document.body.appendChild(div);
        console.log('添加div', document.body.contains(div));
      }

      if (options.watch) {
        el._observe = new MutationObserver(() => {
          if (!document.body.contains(div)) {
            document.body.appendChild(div);
          }
        });
        el._observe.observe(document.body, {
          childList: true
        });

        el._watermarkObsrve = new MutationObserver((mutationsList) => {
          const node = mutationsList[0].target as HTMLElement;
          node.style.backgroundImage = `url(${base64Url})`;
          console.log('mutationsList', mutationsList);
        });
        el._watermarkObsrve.observe(div, {
          attributes: true,
          attributeFilter: ['style', 'class']
        });
      }
    },
    updated(el, binding) {
      const { text, ...options } = binding.value;
      const base64Url = generateWatermark(text, options);
      el._watermark.style.backgroundImage = `url(${base64Url})`;
      console.log('updated');
    },
    unmounted(el) {
      el._observe?.disconnect();
      el._watermarkObsrve?.disconnect();
    }
  });
};
